App({

  globalData: {
    cityList: null,
    signInStatus: null,
    planList: null,
    planTime: 0,
    openId: null,
    location: null,
    locationType: null
  },

  /**
   * 全局变量监听器
   * @param {String} key 
   * @param {function} callback 
   */
  watch: function(key,callback){
    // 全局变量
    var obj = this.globalData;
    // 对全局变量的指定key值进行数据劫持
    Object.defineProperty(obj,key,{
      configurable: true,
      enumerable: true,
      set: function(value){
        // 将该key值的读取绑定到全局变量中另一个key上
        this[key+'Value'] = value;
        // 回调
        callback(value);
      },
      get: function(){
        // 将该key值的读取设置到全局变量中另一个key上
        return this[key+'Value'];
      }
    })
  },

  /**
   * 获取全国三级地名-阿里云
   */
  getCity: function(){
    // 获取全国三级地名-本地json
    this.getWeatherCityList();
    wx.request({
      url: 'https://jisuarea.market.alicloudapi.com/area/all',
      header: {
        'Authorization': 'APPCODE b0eceff9476841588287706ca6819e6e'
      },
      success: res=>{
          let result = res.data.result;
          let cityList = {};
          for(var t of result){
            if(t.parentid==0&&t.name!='国外'){
              // 省
              cityList[t.name] = {};
            }else{
              for(var i in cityList){
                if(t.parentname == i&&t.name!='离岛'){
                  // 市
                  cityList[i][t.name]=[];
                  break;
                }
                if(i!='澳门'){
                  var flag = false;
                  for(var j in cityList[i]){
                    // 区
                    if(t.parentname == j){
                      cityList[i][j].push(t.name);
                      flag = true;
                      break;
                    }
                  }
                  if(flag) break;
                }
              }
            }
          }
          // 港澳台分布以本地json为准
          cityList['香港'] =this.globalData.weatherCityList['香港'];
          cityList['澳门'] = this.globalData.weatherCityList['澳门'];
          cityList['台湾'] =this.globalData.weatherCityList['台湾'];

          this.globalData.cityList = cityList;
          console.log(this.globalData.cityList);
      },
      fail: err=>{
        // 失败重试
        console.error(err);
        this.getCity();
      }
    })
  },

  /**
   * 获取本地天气地名
   */
  getWeatherCityList(){
    let weatherCityList = require('assets/data/weatherCityList').weatherCityList;
    let cityList = {};
    for(var t of weatherCityList){
      if(!cityList[t.provcn]) cityList[t.provcn] = {};
      if(!cityList[t.provcn][t.districtcn]&&t.provcn!=t.districtcn) cityList[t.provcn][t.districtcn] = [];
      if(t.provcn==t.districtcn&&t.provcn!=t.namecn){
        cityList[t.provcn][t.namecn] = []
      }else{
        if(t.districtcn!=t.namecn){
          cityList[t.provcn][t.districtcn].push(t.namecn);
        }
      }
    }
    this.globalData.weatherCityList = cityList;
  },

  /**
   * 从本地获取处理好的天气地名
   */
  getPreCityList(){
    this.globalData.cityList = require('assets/data/preCityList').preCityList;
    console.log(this.globalData.cityList);
  },

  /**
   * 动画函数
   * @param {function} that 回调
   * @param {String} name 操作属性名
   * @param {Number} start 初始值
   * @param {Number} end 结束值
   * @param {Number} time 持续时间
   * @param {String} ease 曲线类型
   */
  animation(that,name,start,end,time,ease){
    var nowTime = 20;
    if(!this[ease]) ease = 'easeInOut'
    clearInterval(that.data[name+'AnimationT']);
    // 执行滚动动画时，关闭滚动监听
    that.setData({
      [name+'OnScroll']: true,
      [name+'AnimationT']: setInterval(()=>{
        if(20<time-nowTime){
          that.setData({
            [name]: this.ease(nowTime,start,end-start,time,ease)
          });
          nowTime += 20;
        }else{
          clearInterval(that.data[name+'AnimationT']);
          that.setData({
            [name+'OnScroll']: false,
            [name]: end
          });
        }
      },20)
    })
  },

  /**
   * 运动曲线
   * @param  {Number} t 当前时间
   * @param  {Number} b 初始值
   * @param  {Number} c 变化量
   * @param  {Number} d 持续时间
   * @param  {String} type 曲线类型
   */
  ease(t,b,c,d,type){
    switch(type){
      case 'easeIn':
        // 缓进
        return c*(t/=d)*t + b;
      case 'easeOut':
        // 缓出
        return -c *(t/=d)*(t-2) + b;
      case 'easeInOut':
        // 缓动
        if ((t/=d/2) < 1) return c/2*t*t + b;
        return -c/2 * ((--t)*(t-2) - 1) + b;
      default:
        // 线性
        return c*t/d + b;
    }
  },

  // 获取用户openId
  getOpenId(){
    wx.cloud.callFunction({
      name: 'getOpenId',
      success: res=>{
        console.log(res,'用户openId');
        this.globalData.openId = res.result;
      },
      fail: err=>{
        console.error(err);
        // 失败无限重试
        this.getOpenId();
      }
    });
  },

  /**
   * 获取用户经纬度
   */
  getLocation(callback){
    // 获取精确位置
    wx.getLocation({
      type: 'wgs84',
      success: res=>{
        // 纬度
        let lat = res.latitude
        // 经度
        let lng = res.longitude
        // 经纬度保存到全局变量
        this.globalData.location = {
          lat,
          lng
        }
        this.globalData.locationType = 'GPS';
        console.log(this.globalData.location,this.globalData.locationType);
        // 回调
        if(callback) callback(lat,lng);
      },
      fail: err=>{
        // 未授权或获取定位失败
        console.log(err)
        // IP定位
        wx.request({
          url: 'https://apis.map.qq.com/ws/location/v1/ip',
          data:{
            key: 'FM6BZ-R3VKW-54HRX-O7HMH-FWMVJ-V2BOT'
          },
          success: res=>{
            let ip = res.data.result.ip;
            let location = res.data.result.location;
            this.globalData.ip = ip;
            this.globalData.location = location;
            this.globalData.locationType = 'IP';
            console.log(location,'IP',ip);
            // 回调
            if(callback) callback(location.lat,location.lng);
          }
        });
      }
    });
  },
  
  /**
   * 获取用户行程提醒信息
   */
  getUserPlan(){
    wx.cloud.callFunction({
      name: 'getUserPlan',
      success: res=>{
        console.log(res,'用户行程提醒信息');
        if(res.result&&res.result.code){
          let data = res.result.data;
          data.sort((a,b)=>b.id-a.id);
          this.globalData.planList = data;
        }
      },
      fail: console.error
    });
  },

  /**
   * 获取用户签到信息
   */
  getSignInStatus(){
    wx.showLoading({
      title: '加载中',
      mask: true
    });
    wx.cloud.callFunction({
      name: 'getSignInStatus',
      success: res=>{
        console.log(res,'用户签到信息');
        if(res.result&&res.result.code){
          this.globalData.signInStatus = res.result.data;
          if(this.globalData.signInStatus.planTime){
            this.globalData.planTime = this.globalData.signInStatus.planTime;
          }
        }
      },
      fail: console.error,
      complete: ()=>{
        wx.hideLoading();
      }
    });
  },

  /**
   * 用户签到
   */
  signIn(callback){
    wx.showLoading({
      title: '加载中',
      mask: true
    });
    wx.cloud.callFunction({
      name: 'signIn',
      success: res=>{
        console.log(res,'用户签到');
        if(res.result.code){
          this.globalData.signInStatus = res.result.data;
        }
        if(callback) callback(res.result.msg);
      },
      fail: console.error,
      complete: ()=>{
        wx.hideLoading();
      }
    });
  },

  /**
   * 用户补签
   */
  reSign(callback){
    wx.showLoading({
      title: '加载中',
      mask: true
    });
    wx.cloud.callFunction({
      name: 'reSign',
      success: res=>{
        console.log(res,'用户补签');
        if(res.result.code){
          this.globalData.signInStatus = res.result.data;
        }
        if(callback) callback(res.result.msg);
      },
      fail: console.error,
      complete: ()=>{
        wx.hideLoading();
      }
    });
  },

  /**
   * 当小程序初始化完成时，会触发 onLaunch（全局只触发一次）
   */
  onLaunch: function () {
    // // 获取全国三级地名-阿里云
    // this.getCity();
    // 从本地获取预设三级地名
    this.getPreCityList();
    // 初始化云环境
    wx.cloud.init({
      env: 'echo-6gdkj7vze65b6844',
      traceUser: true
    });
    // 获取用户openId
    this.getOpenId();
    // 获取用户签到信息
    this.getSignInStatus();
    // 获取用户行程提醒信息
    this.getUserPlan();
  },

  /**
   * 当小程序启动，或从后台进入前台显示，会触发 onShow
   */
  onShow: function (options) {
    
  },

  /**
   * 当小程序从前台进入后台，会触发 onHide
   */
  onHide: function () {
    
  },

  /**
   * 当小程序发生脚本错误，或者 api 调用失败时，会触发 onError 并带上错误信息
   */
  onError: function (msg) {
    
  }
})
